import pandas as pd
from sklearn.model_selection import GroupKFold
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
from xgboost import XGBRegressor
from sklearn.ensemble import RandomForestRegressor, AdaBoostRegressor, GradientBoostingRegressor, ExtraTreesRegressor
from sklearn.linear_model import LinearRegression, Ridge, Lasso, ElasticNet
from sklearn.svm import SVR
from sklearn.neighbors import KNeighborsRegressor
from sklearn.tree import DecisionTreeRegressor
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

# 读取数据
data_path = 'D:\\学习&科研\\华为手表项目\\华为数据\\试验记录表\\all_stages_df_statistics.csv'
df = pd.read_csv(data_path)

# 将 polar_hr 和 polar_rr 列转换为适合模型的格式
df['polar_hr'] = df['polar_hr'].apply(lambda x: eval(x)[0] if isinstance(eval(x), list) and len(eval(x)) > 0 else 0)
df['polar_rr'] = df['polar_rr'].apply(lambda x: eval(x)[0] if isinstance(eval(x), list) and len(eval(x)) > 0 else 0)

# 筛选状态为 running 的数据
df = df[df['state'] == 'running']

# 初始化 GroupKFold
gkf = GroupKFold(n_splits=10)

# 选择特征和目标变量
X = df[['speed','polar_hr_mean','polar_hr_min','polar_hr_max','polar_hr_median',
        'polar_hr_q1','polar_hr_q3','polar_rr_mean','polar_rr_median','polar_rr_q1','polar_rr_q3','sex','age','hight','weight'
    
]].values  # 使用 .values 以确保格式正确
y = df['physiology_RPE'].values
groups = df['number']  # 用于分组的列

# 初始化模型字典
models = {
    'XGBoost': XGBRegressor(n_estimators=200, random_state=42),
    'Random Forest': RandomForestRegressor(n_estimators=200, random_state=42),
    'Linear Regression': LinearRegression(),
    'Support Vector Regression': SVR(),
    'Decision Tree': DecisionTreeRegressor(),
    'Ridge Regression': Ridge(),
    'Lasso Regression': Lasso(),
    'Elastic Net': ElasticNet(),
    'KNN Regression': KNeighborsRegressor(),
    'AdaBoost Regression': AdaBoostRegressor(n_estimators=200),
    'Gradient Boosting': GradientBoostingRegressor(n_estimators=200),
    'Extra Trees': ExtraTreesRegressor(n_estimators=200),
    # 'Deep Learning': None  # 添加深度学习模型占位符
}

# 构建和编译深度学习模型
def create_dl_model():
    model = keras.Sequential([
        layers.Dense(64, activation='relu', input_shape=(X.shape[1],)),
        layers.Dense(32, activation='relu'),
        layers.Dense(1)
    ])
    model.compile(optimizer='adam', loss='mean_squared_error')
    return model

# 初始化结果列表
results = {name: [] for name in models.keys()}
all_y_true = {name: [] for name in models.keys()}
all_y_pred = {name: [] for name in models.keys()}

# 使用 GroupKFold 进行分组划分
for train_index, test_index in gkf.split(X, y, groups=groups):
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]

    # 遍历模型进行训练和评估
    for name in models.keys():
        if name == 'Deep Learning':
            # 创建和训练深度学习模型
            dl_model = create_dl_model()
            dl_model.fit(X_train, y_train, epochs=100, verbose=0)

            # 预测
            y_pred = dl_model.predict(X_test).flatten()  # .flatten() 转换为一维数组
        else:
            # 训练其他模型
            model = models[name]  # 获取模型
            model.fit(X_train, y_train)

            # 预测
            y_pred = model.predict(X_test)

        # 评估模型
        mse = mean_squared_error(y_test, y_pred)
        r2 = r2_score(y_test, y_pred)
        mae = mean_absolute_error(y_test, y_pred)

        # 保存每个模型的结果
        results[name].append({
            'Mean Squared Error': mse,
            'R² Score': r2,
            'Mean Absolute Error': mae
        })

        # 保存所有的真实值和预测值
        all_y_true[name].extend(y_test)
        all_y_pred[name].extend(y_pred)

# 汇总所有模型的结果
summary_results = []

for name in models.keys():
    results_df = pd.DataFrame(results[name])
    overall_mse = mean_squared_error(all_y_true[name], all_y_pred[name])
    overall_r2 = r2_score(all_y_true[name], all_y_pred[name])
    overall_mae = mean_absolute_error(all_y_true[name], all_y_pred[name])
    
    summary_results.append({
        'Model': name,
        'Overall Mean Squared Error': overall_mse,
        'Overall R² Score': overall_r2,
        'Overall Mean Absolute Error': overall_mae
    })

# 将结果保存到 DataFrame
summary_df = pd.DataFrame(summary_results)

# 输出每个模型的结果
for name in models.keys():
    print(f"{name} Results:")
    print(pd.DataFrame(results[name]))
    print('-' * 40)

# 输出汇总结果
print("Summary Results:")
print(summary_df)

# 保存汇总结果到 CSV 文件
summary_df.to_csv('model_evaluation_summary.csv', index=False)
